package pira.parser.http;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import pira.db.excute.DBScanner;
import pira.db.ui.GraphDBUI;
import pira.elements.Author;

public class CiteSeerX extends PageParser{
	
	private String keyWords;
	private String[] result;
	private DBScanner dbs;
	private String[] authors;
	private ArrayList<Article> citedArticles;
	private ArrayList<Article> references;
	private String title;
	private String line;
	
	public int getResultNum() {
		return resultNum;
	}
	
	public ArrayList<Article> getArticles() {
		return citedArticles;
	}
	
	public ArrayList<Article> getReferences() {
		return references;
	}
	
	public CiteSeerX(String keyWords, String[] authors, DBScanner dbs) {
		super();
		this.keyWords= keyWords;
		this.authors= authors;
		this.dbs= dbs;
		this.initiate();
	}
	
	private void initiate() {
		this.url= generateURL();
		this.result= new String[4];
		this.dbs.dbTime= 0;
		this.dbs.requestTime= 0;
		try {
			this.readContent(url);
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.resultNum= getResultNumber();
	}
	
	private String regulate(String str) {
		str = str.trim();
		Pattern p = Pattern.compile("[.,\"\\?!:']");// 增加对应的标点
		Matcher m = p.matcher(str);
		str = m.replaceAll(" ");
		p = Pattern.compile(" {2,}");// 去除多余空格
		m = p.matcher(str);
		str = m.replaceAll(" ").toLowerCase();
		return str;
	}
	
	@Override
	protected String generateURL() {
		keyWords.trim();
		if (keyWords.charAt(keyWords.length()-1) == '.')
			keyWords= keyWords.substring(0, keyWords.length()-1);
		String[] parts= keyWords.split(" ");
		String url= PREFIX + SEARCH + parts[0];
		for (int i= 1; i < parts.length; i++) {
			url= url + "+" +parts[i];
		}
		url= url + SEARCHSUFFIX;
		keyWords = regulate(keyWords);
		return url;
	}
	
	@Override
	public void parse() {
		dbs.sysTime= System.currentTimeMillis();
		if (this.isResultFound()) {
			System.out.println("Paper found in CiteSeerX!");
			title = result[0];
			line = result[1];
			try {
				this.searchCitedFiles();
				this.searchReferenceFiles();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("Paper not found in CiteSeerX!");
			resultNum = 0;
			dbs.requestTime = System.currentTimeMillis() - dbs.sysTime;
		}
	}
	
	@Override
	protected boolean parseResult() {
		int index = -1;
		boolean found= false;
		String title = null;
		
		if ((index = page.indexOf(RESULT)) != -1) {
			String mainContents = page.substring(index);
			String[] results = mainContents.split(BLOCKHIGHLIGHT);
			
			Author a1 = new Author();
			Author a2 = new Author();
			// search and match the first 3 results
			lable:
			for (int i = 1; i < Math.min(results.length, 3); i++) {
				title = this.getTitle(results[i]);
				if (regulate(title).equals(keyWords)) {
					String[] names= this.getAuthors(results[i]);
					
					for (String name:names) {
						a1.setName(name);
						for (String author:authors) {
							a2.setName(author);
							if (a1.equals(a2)) {
								found= true;
								result[0]= title;
								result[1]= results[i];
								break lable;
							}
						}
					}
				}
				System.out.println();
			}
		}
		return found;
	}

	private boolean isResultFound() {
		boolean found= false;
		if (resultNum != 0 && parseResult())
			found= true;
		return found;
	}

	private void searchCitedFiles() throws Exception {
		this.getCiteURL(title, line);
//for (int i = 0; i < result.length; i++)
//	System.out.println(result[i]);
		if (!result[1].equals(GraphDBUI.NOT_EXIST)) {
			CiteURL cu = new CiteURL(result, dbs);
			cu.parse();
			resultNum = cu.getResultNumber();
			citedArticles = cu.getArticles();
		} else
			resultNum = 0;
	}

	private void searchReferenceFiles() throws Exception {
		String paperURL = this.getPaperURL(title, line);
		PaperCitation pc = new PaperCitation(paperURL);
//		pc.getAuthors();
		pc.parse();
		references = pc.getReferences();
	}
	
	public void parseReference() {
		if (this.isResultFound()) {
			System.out.println("Paper found in CiteSeerX!");
			title = result[0];
			line = result[1];
			try {
				this.searchReferenceFiles();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("Paper not found in CiteSeerX!");
			resultNum = 0;
		}
	}
	
	// test
	public void shutDown() {
		dbs.getGraphDBUI().shutDown();
	}
	
	private String getPaperURL(String title, String line) {
		int beginIndex, endIndex;
		
		if ((beginIndex= line.indexOf("?doi=")) != -1) {
			line= line.substring(beginIndex);
			beginIndex= 0;
			endIndex= line.indexOf("\">");
			line= line.substring(beginIndex, endIndex);
			
			return PAPERPREFIX + line;
		} else
			return null;
	}
	
	private void getCiteURL(String title, String line) {
		int beginIndex, endIndex;
		String[] citationInfo= new String[3];
		if ((beginIndex= line.indexOf("<li class=\"char_increased\">")) != -1) {
			line= line.substring(beginIndex);
			beginIndex= 0;
			endIndex= line.indexOf("</li>");
			line= line.substring(beginIndex, endIndex);
			
			// find the URL to citations
			int refIndex= 0;
			if ((refIndex = line.indexOf("?cid=")) != -1) {
				
				citationInfo[0] = line.substring(refIndex);
				int refEndIndex = citationInfo[0].indexOf("\"");
				citationInfo[0] = citationInfo[0].substring(0, refEndIndex);
				citationInfo[0] = SHOWCITING + citationInfo[0];

				// find the citation number
				String numbers = null;
				numbers = line.replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll(
						"<[^>]*>", "");
				numbers = numbers.replaceAll("[(/>)<]", "");

				citationInfo[1] = numbers.split(" ")[2];
				citationInfo[2] = numbers.split(" ")[3];

				// String str[]= new String[4];
				for (int k = 0; k < 3; k++) {
					result[k + 1] = citationInfo[k];
				}
			} else {
				result[1]= GraphDBUI.NOT_EXIST;
			}
		}
	}
}
